
#include <QLabel>
#include <QPushButton>
#include <QThreadPool>

#include "MainWindow.h"

#include "Shelf.h"
#include "Writer.h"
#include "Reader.h"


library::MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {

  setWindowFlags(Qt::MSWindowsFixedSizeDialogHint);
  QGridLayout *gridLayout = new QGridLayout(this);

  initDefaultParams();

  gridLayout->addWidget(new QLabel("Shelf`s Size:"), 1, 0);
  shelfSizeParam = new QLineEdit(QString("%1").arg(shelfSize));
  addLineEdit(shelfSizeParam, gridLayout, 1, 1);

  gridLayout->addWidget(new QLabel("Readers Count:"), 2, 0);
  rCountParam = new QLineEdit(QString("%1").arg(readersCount));
  addLineEdit(rCountParam, gridLayout, 2, 1);

  gridLayout->addWidget(new QLabel("Reading Time (in sec.):"), 2, 2);
  rTimeParam = new QLineEdit(QString("%1").arg(readingTime));
  addLineEdit(rTimeParam, gridLayout, 2, 3);

  gridLayout->addWidget(new QLabel("Writers count:"), 3, 0);
  wCountParam = new QLineEdit(QString("%1").arg(writersCount));
  addLineEdit(wCountParam, gridLayout, 3, 1);

  gridLayout->addWidget(new QLabel("Writing Time (in sec.):"), 3, 2);
  wTimeParam = new QLineEdit(QString("%1").arg(writingTime));
  addLineEdit(wTimeParam, gridLayout, 3, 3);

  QPushButton *okButton = new QPushButton("OK");
  gridLayout->addWidget(okButton, 5, 2);
  connect(okButton, SIGNAL(clicked()), this, SLOT(okBtClicked()));

  shelfProgress = new QProgressBar();
  initProgressBar(shelfProgress, gridLayout, "Shelf:", 7);

  activeProgress = new QProgressBar();
  initProgressBar(activeProgress, gridLayout, "Active:", 8);

  waitProgress = new QProgressBar();
  initProgressBar(waitProgress, gridLayout, "Waiting:", 9);

  QWidget *widget = new QWidget(this);
  widget->setLayout(gridLayout);
  setCentralWidget(widget);

}


void library::MainWindow::addLineEdit(QLineEdit *lineEdit, QGridLayout * gridLayout, int row, int col) {

  lineEdit->setInputMask("999");
  gridLayout->addWidget(lineEdit, row, col);

}


void library::MainWindow::initProgressBar(QProgressBar *progress, QGridLayout * gridLayout, const QString &label, int row) {

  progress->setMinimum(0);
  gridLayout->addWidget(new QLabel(label), row, 0);
  gridLayout->addWidget(progress, row, 1, 1, 4);
  progress->setTextVisible(true);

}


void library::MainWindow::shelfProgressSlot() {

  shelfProgress->setValue(shelfProgress->value() + 1);

}


void library::MainWindow::activeProgressSlot() {

  activeProgress->setValue(activeProgress->value() + 1);
  waitProgress->setValue(waitProgress->value() - 1);

}


void library::MainWindow::waitProgressSlot() {

  waitProgress->setValue(waitProgress->value() + 1);
  activeProgress->setValue(activeProgress->value() - 1);

}


void library::MainWindow::okBtClicked() {

  updateParam();

  Shelf *shelf = new Shelf(shelfSize);
  connect(shelf, SIGNAL(newBook()), this, SLOT(shelfProgressSlot()));

  QThreadPool *threadPool = QThreadPool::globalInstance();
  threadPool->setMaxThreadCount(readersCount + writersCount);

  for(int i = 0; i < writersCount; ++i){

    Writer *writer = new Writer(shelf, writingTime);
    connect(writer, SIGNAL(write()), this, SLOT(activeProgressSlot()));
    connect(writer, SIGNAL(edit()), this, SLOT(activeProgressSlot()));
    connect(writer, SIGNAL(wait()), this, SLOT(waitProgressSlot()));
    threadPool->start(writer);

  }

  for(int i = 0; i < readersCount; ++i){

    Reader *reader = new Reader(shelf, readingTime);
    connect(reader, SIGNAL(read()), this, SLOT(activeProgressSlot()));
    connect(reader, SIGNAL(wait()), this, SLOT(waitProgressSlot()));
    threadPool->start(reader);

  }

}


void library::MainWindow::initDefaultParams() {

  shelfSize     = 20;

  readersCount  = 10;
  readingTime   = 2;

  writersCount  = 10;
  writingTime   = 2;

}


void library::MainWindow::updateParam() {

  shelfSize     = shelfSizeParam->text().toInt();
  readersCount  = rCountParam->text().toInt();
  readingTime      = rTimeParam->text().toInt();
  writersCount  = wCountParam->text().toInt();
  writingTime     = wTimeParam->text().toInt();

  shelfProgress->setMaximum(shelfSize);
  activeProgress->setMaximum(writersCount + readersCount);
  waitProgress->setMaximum(writersCount + readersCount);

}



